#pragma once
#include <stdio.h>  
#include <stdlib.h>  
#include <sys/time.h>  
#include <signal.h>  
#include <event2/event.h>  
#include <event2/event_struct.h>  
#include "object_pool.h"
#include <functional>

class AsyncTimer;
typedef std::function<void(void)> timer_callback;

class Timer
{
public:
	Timer()
		:_timeout(nullptr)
	{}
	~Timer()
	{
		destroy();
	}
	void Init(struct event_base* base, int second, timer_callback func_cb, bool loop = false)
	{
		_func_cb = func_cb;
		destroy();
		_tv.tv_usec = 0;
		_tv.tv_sec = second;
		_loop = loop;
		int flag = (_loop) ? EV_PERSIST : 0;
		_timeout = event_new( base, -1, flag, timeout_cb, this);
		//_timeout = evtimer_new(base, -1, 0, timeout_cb, this);
	}
	inline void start()
	{
		if (_timeout)
		{
			evtimer_add(_timeout, &_tv);
		}
	}
	inline void stop()
	{
		if (_timeout)
		{
			evtimer_del(_timeout);
		}
	}
	inline void destroy()
	{
		if (_timeout)
		{
			evtimer_del(_timeout);
			event_free(_timeout);
			_timeout = nullptr;
		}
	}
	static void timeout_cb(int fd, short event, void* arg)
	{
		Timer* self = (Timer*)arg;
		self->_func_cb();
		//if(self->_loop)evtimer_add(self->_timeout, &self->_tv);
	}
private:
	bool _loop;
	struct event* _timeout;
	struct timeval _tv;
	timer_callback _func_cb;
};

class GameTimer
{
public:
	GameTimer() :_timer(nullptr)
	{}
protected:
	inline bool init(Timer* timer)
	{
		_timer = timer;
		return (_timer != nullptr);
	}
	inline void again()
	{
		if (_timer)
		{
			_timer->start();
		}
	}
public:
	inline bool operator = (Timer* timer)
	{
		return init(timer);
	}
	inline bool run()
	{
		if (_timer)
		{
			_timer->start();
			return true;
		}
		return false;
	}
	inline bool start()
	{
		return run();
	}
	inline void stop()
	{
		if (_timer)
		{
			_timer->stop();
		}
	}
public:
	Timer * _timer;
};


class AsyncTimer : public ObjectPool<Timer>
{
public:
	AsyncTimer(struct event_base* base)
		: _base(base)
	{}
	~AsyncTimer()
	{
	}
	//初始化定时器 包含初始化
	bool InitTimer(GameTimer& timer, int seconds, timer_callback fn, bool loop = false)
	{
		return (timer = Async(seconds, loop, fn));
	}
	//运行一次性的定时器
	bool RunOnce(GameTimer& timer, int seconds, timer_callback fn)
	{
		if (timer.run())
		{
			return true;
		}
		timer = Async(seconds, false, fn);
		return timer.run();
	}
protected:
	//reclaim是否会自动回收，即是否是一次性的
	Timer * Async(int seconds, bool loop, timer_callback fn)
	{
		Timer* timer = Pop();
		timer->Init(_base, seconds, fn, loop);
		return timer;
	}

private:
	struct event_base* _base;
};